{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "nbsphinx": "hidden"
   },
   "outputs": [],
   "source": [
    "# Delete this cell to re-enable tracebacks\n",
    "import sys\n",
    "ipython = get_ipython()\n",
    "\n",
    "def hide_traceback(exc_tuple=None, filename=None, tb_offset=None,\n",
    "                   exception_only=False, running_compiled_code=False):\n",
    "    etype, value, tb = sys.exc_info()\n",
    "    value.__cause__ = None  # suppress chained exceptions\n",
    "    return ipython._showtraceback(etype, value, ipython.InteractiveTB.get_exception_only(etype, value))\n",
    "\n",
    "ipython.showtraceback = hide_traceback"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "nbsphinx": "hidden"
   },
   "outputs": [],
   "source": [
    "# JSON output syntax highlighting\n",
    "from __future__ import print_function\n",
    "from pygments import highlight\n",
    "from pygments.lexers import JsonLexer, TextLexer\n",
    "from pygments.formatters import HtmlFormatter\n",
    "from IPython.display import display, HTML\n",
    "from IPython.core.interactiveshell import InteractiveShell\n",
    "\n",
    "InteractiveShell.ast_node_interactivity = \"all\"\n",
    "\n",
    "def json_print(inpt):\n",
    "    string = str(inpt)\n",
    "    formatter = HtmlFormatter()\n",
    "    if string[0] == '{':\n",
    "        lexer = JsonLexer()\n",
    "    else:\n",
    "        lexer = TextLexer()\n",
    "    return HTML('<style type=\"text/css\">{}</style>{}'.format(\n",
    "                formatter.get_style_defs('.highlight'),\n",
    "                highlight(string, lexer, formatter)))\n",
    "\n",
    "globals()['print'] = json_print"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Technical Specification Support\n",
    "\n",
    "### How imports work\n",
    "\n",
    "Imports can be used in different ways depending on the use case and support levels.\n",
    "\n",
    "People who want to support the latest version of STIX 2 without having to make changes, can implicitly use the latest version:<div class=\"alert alert-warning\">\n",
    "\n",
    "**Warning**\n",
    "\n",
    "The implicit import method can cause the code to break between major releases to support a newer approved committee specification. Therefore, not recommended for large scale applications relying on specific object support.\n",
    "\n",
    "</div>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "import stix2\n",
    "\n",
    "stix2.Indicator()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "or,"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "from stix2 import Indicator\n",
    "\n",
    "Indicator()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "People who want to use an explicit version:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "import stix2.v20\n",
    "\n",
    "stix2.v20.Indicator()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "or,"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "from stix2.v20 import Indicator\n",
    "\n",
    "Indicator()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "or even, (less preferred)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "import stix2.v20 as stix2\n",
    "\n",
    "stix2.Indicator()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The last option makes it easy to update to a new version in one place per file, once you've made the deliberate action to do this.\n",
    "\n",
    "People who want to use multiple versions in a single file:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "import stix2\n",
    "\n",
    "stix2.v20.Indicator()\n",
    "stix2.v21.Indicator()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "or,"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "from stix2 import v20, v21\n",
    "\n",
    "v20.Indicator()\n",
    "v21.Indicator()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "or (less preferred):"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "from stix2.v20 import Indicator as Indicator_v20\n",
    "from stix2.v21 import Indicator as Indicator_v21\n",
    "\n",
    "Indicator_v20()\n",
    "Indicator_v21()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### How parsing works\n",
    "If the ``version`` positional argument is not provided the library will make the best attempt using the \"spec_version\" property found on a Bundle, SDOs, SCOs, or SROs.\n",
    "\n",
    "You can lock your [parse()](../api/stix2.parsing.rst#stix2.parsing.parse) method to a specific STIX version by:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<style type=\"text/css\">.highlight .hll { background-color: #ffffcc }\n",
       ".highlight  { background: #f8f8f8; }\n",
       ".highlight .c { color: #408080; font-style: italic } /* Comment */\n",
       ".highlight .err { border: 1px solid #FF0000 } /* Error */\n",
       ".highlight .k { color: #008000; font-weight: bold } /* Keyword */\n",
       ".highlight .o { color: #666666 } /* Operator */\n",
       ".highlight .ch { color: #408080; font-style: italic } /* Comment.Hashbang */\n",
       ".highlight .cm { color: #408080; font-style: italic } /* Comment.Multiline */\n",
       ".highlight .cp { color: #BC7A00 } /* Comment.Preproc */\n",
       ".highlight .cpf { color: #408080; font-style: italic } /* Comment.PreprocFile */\n",
       ".highlight .c1 { color: #408080; font-style: italic } /* Comment.Single */\n",
       ".highlight .cs { color: #408080; font-style: italic } /* Comment.Special */\n",
       ".highlight .gd { color: #A00000 } /* Generic.Deleted */\n",
       ".highlight .ge { font-style: italic } /* Generic.Emph */\n",
       ".highlight .gr { color: #FF0000 } /* Generic.Error */\n",
       ".highlight .gh { color: #000080; font-weight: bold } /* Generic.Heading */\n",
       ".highlight .gi { color: #00A000 } /* Generic.Inserted */\n",
       ".highlight .go { color: #888888 } /* Generic.Output */\n",
       ".highlight .gp { color: #000080; font-weight: bold } /* Generic.Prompt */\n",
       ".highlight .gs { font-weight: bold } /* Generic.Strong */\n",
       ".highlight .gu { color: #800080; font-weight: bold } /* Generic.Subheading */\n",
       ".highlight .gt { color: #0044DD } /* Generic.Traceback */\n",
       ".highlight .kc { color: #008000; font-weight: bold } /* Keyword.Constant */\n",
       ".highlight .kd { color: #008000; font-weight: bold } /* Keyword.Declaration */\n",
       ".highlight .kn { color: #008000; font-weight: bold } /* Keyword.Namespace */\n",
       ".highlight .kp { color: #008000 } /* Keyword.Pseudo */\n",
       ".highlight .kr { color: #008000; font-weight: bold } /* Keyword.Reserved */\n",
       ".highlight .kt { color: #B00040 } /* Keyword.Type */\n",
       ".highlight .m { color: #666666 } /* Literal.Number */\n",
       ".highlight .s { color: #BA2121 } /* Literal.String */\n",
       ".highlight .na { color: #7D9029 } /* Name.Attribute */\n",
       ".highlight .nb { color: #008000 } /* Name.Builtin */\n",
       ".highlight .nc { color: #0000FF; font-weight: bold } /* Name.Class */\n",
       ".highlight .no { color: #880000 } /* Name.Constant */\n",
       ".highlight .nd { color: #AA22FF } /* Name.Decorator */\n",
       ".highlight .ni { color: #999999; font-weight: bold } /* Name.Entity */\n",
       ".highlight .ne { color: #D2413A; font-weight: bold } /* Name.Exception */\n",
       ".highlight .nf { color: #0000FF } /* Name.Function */\n",
       ".highlight .nl { color: #A0A000 } /* Name.Label */\n",
       ".highlight .nn { color: #0000FF; font-weight: bold } /* Name.Namespace */\n",
       ".highlight .nt { color: #008000; font-weight: bold } /* Name.Tag */\n",
       ".highlight .nv { color: #19177C } /* Name.Variable */\n",
       ".highlight .ow { color: #AA22FF; font-weight: bold } /* Operator.Word */\n",
       ".highlight .w { color: #bbbbbb } /* Text.Whitespace */\n",
       ".highlight .mb { color: #666666 } /* Literal.Number.Bin */\n",
       ".highlight .mf { color: #666666 } /* Literal.Number.Float */\n",
       ".highlight .mh { color: #666666 } /* Literal.Number.Hex */\n",
       ".highlight .mi { color: #666666 } /* Literal.Number.Integer */\n",
       ".highlight .mo { color: #666666 } /* Literal.Number.Oct */\n",
       ".highlight .sa { color: #BA2121 } /* Literal.String.Affix */\n",
       ".highlight .sb { color: #BA2121 } /* Literal.String.Backtick */\n",
       ".highlight .sc { color: #BA2121 } /* Literal.String.Char */\n",
       ".highlight .dl { color: #BA2121 } /* Literal.String.Delimiter */\n",
       ".highlight .sd { color: #BA2121; font-style: italic } /* Literal.String.Doc */\n",
       ".highlight .s2 { color: #BA2121 } /* Literal.String.Double */\n",
       ".highlight .se { color: #BB6622; font-weight: bold } /* Literal.String.Escape */\n",
       ".highlight .sh { color: #BA2121 } /* Literal.String.Heredoc */\n",
       ".highlight .si { color: #BB6688; font-weight: bold } /* Literal.String.Interpol */\n",
       ".highlight .sx { color: #008000 } /* Literal.String.Other */\n",
       ".highlight .sr { color: #BB6688 } /* Literal.String.Regex */\n",
       ".highlight .s1 { color: #BA2121 } /* Literal.String.Single */\n",
       ".highlight .ss { color: #19177C } /* Literal.String.Symbol */\n",
       ".highlight .bp { color: #008000 } /* Name.Builtin.Pseudo */\n",
       ".highlight .fm { color: #0000FF } /* Name.Function.Magic */\n",
       ".highlight .vc { color: #19177C } /* Name.Variable.Class */\n",
       ".highlight .vg { color: #19177C } /* Name.Variable.Global */\n",
       ".highlight .vi { color: #19177C } /* Name.Variable.Instance */\n",
       ".highlight .vm { color: #19177C } /* Name.Variable.Magic */\n",
       ".highlight .il { color: #666666 } /* Literal.Number.Integer.Long */</style><div class=\"highlight\"><pre><span></span><span class=\"p\">{</span>\n",
       "    <span class=\"nt\">&quot;type&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;indicator&quot;</span><span class=\"p\">,</span>\n",
       "    <span class=\"nt\">&quot;id&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;indicator--dbcbd659-c927-4f9a-994f-0a2632274394&quot;</span><span class=\"p\">,</span>\n",
       "    <span class=\"nt\">&quot;created&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;2017-09-26T23:33:39.829Z&quot;</span><span class=\"p\">,</span>\n",
       "    <span class=\"nt\">&quot;modified&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;2017-09-26T23:33:39.829Z&quot;</span><span class=\"p\">,</span>\n",
       "    <span class=\"nt\">&quot;name&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;File hash for malware variant&quot;</span><span class=\"p\">,</span>\n",
       "    <span class=\"nt\">&quot;pattern&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;[file:hashes.md5 = &#39;d41d8cd98f00b204e9800998ecf8427e&#39;]&quot;</span><span class=\"p\">,</span>\n",
       "    <span class=\"nt\">&quot;valid_from&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;2017-09-26T23:33:39.829952Z&quot;</span><span class=\"p\">,</span>\n",
       "    <span class=\"nt\">&quot;labels&quot;</span><span class=\"p\">:</span> <span class=\"p\">[</span>\n",
       "        <span class=\"s2\">&quot;malicious-activity&quot;</span>\n",
       "    <span class=\"p\">]</span>\n",
       "<span class=\"p\">}</span>\n",
       "</pre></div>\n"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from stix2 import parse\n",
    "\n",
    "indicator = parse(\"\"\"{\n",
    "    \"type\": \"indicator\",\n",
    "    \"id\": \"indicator--dbcbd659-c927-4f9a-994f-0a2632274394\",\n",
    "    \"created\": \"2017-09-26T23:33:39.829Z\",\n",
    "    \"modified\": \"2017-09-26T23:33:39.829Z\",\n",
    "    \"labels\": [\n",
    "        \"malicious-activity\"\n",
    "    ],\n",
    "    \"name\": \"File hash for malware variant\",\n",
    "    \"pattern\": \"[file:hashes.md5 = 'd41d8cd98f00b204e9800998ecf8427e']\",\n",
    "    \"valid_from\": \"2017-09-26T23:33:39.829952Z\"\n",
    "}\"\"\", version=\"2.0\")\n",
    "print(indicator.serialize(pretty=True))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "In the example above if a 2.1 or higher object is parsed, the operation will fail."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### How custom content works\n",
    "\n",
    "[CustomObject](../api/v21/stix2.v21.sdo.rst#stix2.v21.sdo.CustomObject), [CustomObservable](../api/v21/stix2.v21.observables.rst#stix2.v21.observables.CustomObservable), [CustomMarking](../api/v21/stix2.v21.common.rst#stix2.v21.common.CustomMarking) and [CustomExtension](../api/v21/stix2.v21.common.rst#stix2.v21.common.CustomExtension) must be registered explicitly by STIX version. This is a design decision since properties or requirements may change as the STIX Technical Specification advances.\n",
    "\n",
    "You can perform this by:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "import stix2\n",
    "\n",
    "# Make my custom observable available in STIX 2.0\n",
    "@stix2.v20.CustomObservable('x-new-object-type',\n",
    "                            [(\"prop\", stix2.properties.BooleanProperty())])\n",
    "class NewObject2(object):\n",
    "    pass\n",
    "\n",
    "\n",
    "# Make my custom observable available in STIX 2.1\n",
    "@stix2.v21.CustomObservable('x-new-object-type',\n",
    "                            [(\"prop\", stix2.properties.BooleanProperty())])\n",
    "class NewObject2(object):\n",
    "    pass"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.9.2"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 1
}
